class Fetion < ActiveRecord::Base
  
  validates_presence_of :mobile,
    :name
  validates_uniqueness_of :mobile,
    :name

  def full?
    max_users_count == users_count
  end  
  
  def seat_percent
    users_count * 100.0 / max_users_count 
  end
  
  def reset_unread_messages_count!
    update_attributes! :unread_application_confirmed_messages_count =>  FetionMessage::ApplicationConfirmed.count_by_fetion_id_and_status(id,'unread'),
    :unread_buddy_application_messages_count => FetionMessage::BuddyApplication.count_by_fetion_id_and_status(id,'unread'),
    :unread_buddy_messages_count => FetionMessage::BuddyMessage.count_by_fetion_id_and_status(id,'unread'),    
    :unread_buddy_state_messages_count => FetionMessage::BuddyState.count_by_fetion_id_and_status(id,'unread'),
    :unread_client_state_messages_count => FetionMessage::ClientState.count_by_fetion_id_and_status(id,'unread')
  end
  
  def before_save
    encode_password! if encrypted_password_changed?
  end

  def invert_standing!
    update_attribute :standing,
      standing.master? ? 'slave' : 'master'
  end
  
  def password
    decode_password
  end
  
  def status
    ActiveSupport::StringInquirer.new(self[:status])
  end
  
  def standing
    ActiveSupport::StringInquirer.new(self[:standing])
  end
  
  def status!(new_status)
    self.status = new_status
    self.logined_at = Time.now if new_status == 'ONLINE' and status_changed?
    save false
  end
  
  def allow_login?
    status.NEW? or status.LOGOUT? or status.LOGIN_FAIL? or status.NET_ERROR? or status.OTHER_LOGIN?
  end
  
  def allow_logout?
    status.LOGIN? or status.ONLINE?
  end
  
  def self.empty_one
    first( 
      :conditions => [
        'max_users_count > users_count and standing = ?',
        'master'
      ],
      :order => ' id asc'
    )
  end
  
  def notifies_from_lite_fetion!
    logger.debug "开始抓取#{mobile}消息"
    @notifies = LiteFetionNotify.find(:all, 
      :params => {
        :mobile => mobile 
      }
    ) 
    logger.debug "#{@notifies.size}条"
    @notifies.each_with_index do |notify,index|
      case notify.notify_type
      when 'APPLICATION_CONFIRMED'
        FetionMessage::ApplicationConfirmed.create!(
          :fetion_id => id,
          :mobile => notify.mobile,
          :fetion_user_id => notify.user_id,
          :fetion_sid => notify.s_id,
          :agreed => notify.agreed
        )
      when 'BUDDY_APPLICATION'
        FetionMessage::BuddyApplication.create!(
          :fetion_id => id,
          :mobile => notify.mobile,
          :fetion_user_id => notify.user_id,
          :fetion_sid => notify.s_id,
          :desc => notify.desc
        )
      when 'BUDDY_MESSAGE'
        FetionMessage::BuddyMessage.create!(
          :fetion_id => id,
          :mobile => notify.mobile,
          :fetion_user_id => notify.user_id,
          :fetion_sid => notify.s_id,
          :message => notify.message,
          :sent_on => notify.sent_on
        )
      when 'BUDDY_STATE'
        FetionMessage::BuddyState.create!(
          :fetion_id => id,
          :mobile => notify.mobile,
          :fetion_user_id => notify.user_id,
          :fetion_sid => notify.s_id,
          :before_state => notify.before_state,
          :current_state => notify.current_state
        )
      when 'CLIENT_STATE'
        FetionMessage::ClientState.create!(
          :fetion_id => id,
          :client_state => notify.client_state
        )
        status! notify.client_state
      else
        logger.error "unknown Notify: #{notify.notify_type}"
      end
    end
    reset_unread_messages_count! if @notifies.any?
#    logger.debug "更新客户端状态"
#    @lite_fetion = LiteFetion.new(
#      :id => mobile
#    ).get(:client_state)
#    status! @lite_fetion['state']
  end
  
  def reset_users_count!
    self.users_count = User.count(
      :conditions => ['fetion_id = ? and lite_fetion_status = ? ', id, 'success']
    )
    save false
  end
  
  private 
  # 加密密码
  def encode_password!
    self.encrypted_password = Base64.encode64(encrypted_password).chop
  end
  
  def decode_password
    Base64.decode64(encrypted_password)
  end      
end
